//
//  XWSpeechAudiometryBarChartView.swift
//  XWHAOfflineFitting
//
//  Created by edy on 2025/9/12.
//

import UIKit
import Charts

class XWSpeechAudiometryBarChartView: AppBarChartView {
    
    lazy var titleLb = UILabel()
    lazy var xUnitLb = UILabel()
    lazy var yUnitLb = UILabel()

    
    var volumeUnitText: String {
        "dB"
    }
    
    var titleLbHeight: CGFloat {
        24
    }
    var unitLbHeight: CGFloat {
        24
    }
    
    override func addSubViews() {
        super.addSubViews()
        
        addSubview(titleLb)

        addSubview(xUnitLb)
        addSubview(yUnitLb)
        
        configTitleLb(titleLb)
        configUnitLb(xUnitLb)
        configUnitLb(yUnitLb)
        
        xUnitLb.textAlignment = .right
        
        titleLb.text = "言语测听图"
        xUnitLb.text = "HL (db)"
        yUnitLb.text = "得分（%）"
    }
    
    func configTitleLb(_ lb: UILabel) {
        lb.font = AppFont.harmonyOSSans(ofSize: 17, weight: .medium)
        lb.textColor = majorTextColor
        lb.textAlignment = .center
    }
    
    func configUnitLb(_ lb: UILabel) {
        lb.font = AppFont.harmonyOSSans(ofSize: 10, weight: .regular)
        lb.textAlignment = .left
        lb.textColor = minorTextColor
    }
    
    override func relayoutSubViews() {
        titleLb.snp.makeConstraints { make in
            make.height.equalTo(titleLbHeight)
            make.left.right.equalToSuperview()
            make.top.equalToSuperview()
        }
        let chartViewTopInset: CGFloat = unitLbHeight + titleLbHeight
        let chartViewBottomInset: CGFloat = unitLbHeight
        chartView.snp.makeConstraints { make in
            make.left.equalToSuperview().inset(140)
            make.right.equalToSuperview().inset(140)
            make.top.equalToSuperview().inset(chartViewTopInset)
            make.bottom.equalToSuperview().inset(chartViewBottomInset)
        }
        yUnitLb.snp.makeConstraints { make in
            make.left.equalTo(chartView).offset(24)
            make.height.equalTo(unitLbHeight)
            make.top.equalTo(titleLb.snp.bottom)
            make.width.lessThanOrEqualTo(240)
        }
        xUnitLb.snp.makeConstraints { make in
            make.right.equalTo(chartView)
            make.height.equalTo(unitLbHeight)
            make.bottom.equalToSuperview()
            make.width.lessThanOrEqualTo(240)
        }
    }
    
    func updateChart(leftSdsDbHlValue: Int, leftSdsPercentValue: Int, rightSdsDbHlValue: Int, rightSdsPercentValue: Int) {
        chartView.data = getChartData(leftSdsDbHlValue: leftSdsDbHlValue, leftSdsPercentValue: leftSdsPercentValue, rightSdsDbHlValue: rightSdsDbHlValue, rightSdsPercentValue: rightSdsPercentValue)
    }
    func getChartData(leftSdsDbHlValue: Int, leftSdsPercentValue: Int, rightSdsDbHlValue: Int, rightSdsPercentValue: Int) -> BarChartData {
        var cdSetList: [BarChartDataSet] = []
        if leftSdsDbHlValue > 0, leftSdsPercentValue > 0 {
            let set = getChartDataSet(xValue: leftSdsDbHlValue.double, yValue: leftSdsPercentValue.double)
            set.colors = [leftEarColor]
            set.label = "left"
            
            cdSetList.append(set)
        }
        
        
        if rightSdsDbHlValue > 0, rightSdsPercentValue > 0 {
            let set = getChartDataSet(xValue: rightSdsDbHlValue.double, yValue: rightSdsPercentValue.double)
            set.colors = [rightEarColor]
            set.label = "right"
            
            cdSetList.append(set)
        }
        
        let chartData = BarChartData(dataSets: cdSetList)
        return chartData
    }
    
    func getChartDataSet(xValue: Double, yValue: Double) -> BarChartDataSet {
        var dataEntries: [BarChartDataEntry] = []
        
        let entry = BarChartDataEntry(x: xValue, y: yValue)
        dataEntries.append(entry)
        
        let chartDataSet = BarChartDataSet(entries: dataEntries, label: "")

        chartDataSet.colors = [UIColor(hex: 0xEB5763)!]
        chartDataSet.drawValuesEnabled = false
        
        return chartDataSet
    }

}

extension XWSpeechAudiometryBarChartView {
    
    override func configXAxis() {
        chartView.maxVisibleCount = 1000
        
        chartView.xAxis.labelPosition = .bottom
                
        let axisMinimum: Double = WDRCModule.saDdsDbHlMinValue.double
        let axisMaximum: Double = WDRCModule.saDdsDbHlMaxValue.double
        let granularity: Double = 10
        let labelCount = (axisMaximum.int - (axisMinimum.int)) / 10 + 1
        
        chartView.xAxis.axisMaxLabels = labelCount
        
        chartView.xAxis.axisMinimum = axisMinimum
        chartView.xAxis.granularity = granularity
        chartView.xAxis.axisMaximum = axisMaximum
        
        chartView.xAxis.labelCount = chartView.xAxis.axisMaxLabels
        chartView.xAxis.forceLabelsEnabled = true
//        chartView.xAxis.granularityEnabled = true
        
        chartView.xAxis.axisLineWidth = 1
        chartView.xAxis.axisLineColor = UIColor.black.withAlphaComponent(0.05)
        chartView.xAxis.drawAxisLineEnabled = true
        
        chartView.xAxis.gridLineWidth = 1
        chartView.xAxis.gridColor = UIColor.black.withAlphaComponent(0.05)
        chartView.xAxis.drawGridLinesEnabled = true
        
        chartView.xAxis.labelFont = AppFont.harmonyOSSans(ofSize: 10)
        chartView.xAxis.labelTextColor = minorTextColor
        chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: { [weak self] value, _ in
            let x = value.int
            var ret = x.string
            guard let self = self else {
                return ret
            }
            
            ret = self.getAxisValue(index: x)
            
            return ret
        })
    }
    
    func getAxisValue(index: Int) -> String {
        let value1 = index.double / 10
        let value2 = value1 - value1.int.double

        var ret = ""
        
        if value2 == 0 {
            ret = index.string
        } else {
            ret = ""
        }
        
        return ret
    }
    
    override func configYAxis() {
        //        chartView.leftAxis.enabled = false
        chartView.maxVisibleCount = 1000
        
        let axisMinimum: Double = WDRCModule.saDdsPercentMinValue.double
        let axisMaximum: Double = WDRCModule.saDdsPercentMaxValue.double
        let granularity: Double = 10
        let labelCount = (axisMaximum.int - (axisMinimum.int)) / 10 + 1
        let isInverted = false
        chartView.leftAxis.inverted = isInverted
        chartView.leftAxis.axisMinimum = axisMinimum
        chartView.leftAxis.axisMaximum = axisMaximum
        chartView.leftAxis.granularity = granularity
        
//        chartView.leftAxis.axisMaxLabels = labelCount
        
        chartView.leftAxis.setLabelCount(labelCount, force: true)
        
        chartView.rightAxis.inverted = isInverted
        chartView.rightAxis.axisMinimum = axisMinimum
        chartView.rightAxis.axisMaximum = axisMaximum
        chartView.rightAxis.granularity = granularity
//        chartView.leftAxis.axisMaxLabels = labelCount
        chartView.rightAxis.setLabelCount(labelCount, force: true)
        
        let lineColor = UIColor.black.withAlphaComponent(0.05)
        let lineWidth = 0.5
        chartView.leftAxis.axisLineColor = lineColor
        chartView.leftAxis.axisLineWidth = lineWidth
        
        chartView.rightAxis.axisLineColor = lineColor
        chartView.rightAxis.axisLineWidth = lineWidth
        
        chartView.leftAxis.drawGridLinesEnabled = true
        chartView.leftAxis.drawLabelsEnabled = true
        
        chartView.rightAxis.drawGridLinesEnabled = false
        chartView.rightAxis.drawLabelsEnabled = false
        
        chartView.leftAxis.axisLineColor = lineColor
        chartView.leftAxis.axisLineWidth = lineWidth
        
        chartView.leftAxis.gridLineWidth = lineWidth
        chartView.leftAxis.gridColor = lineColor
        
        chartView.rightAxis.gridLineWidth = lineWidth
        chartView.rightAxis.gridColor = lineColor
        
        chartView.leftAxis.labelFont = AppFont.harmonyOSSans(ofSize: 10)
        chartView.leftAxis.labelTextColor = minorTextColor
        
        chartView.rightAxis.labelFont = AppFont.harmonyOSSans(ofSize: 10)
        chartView.rightAxis.labelTextColor = minorTextColor
        
        chartView.leftAxis.valueFormatter = DefaultAxisValueFormatter(block: { [weak self] value, _ in
            var ret = ""
            guard let self = self else {
                return ret
            }
            
            ret = self.getAxisValue(index: value.int)
            
            return ret
        })
    }
    
}

// MARK: - ChartViewDelegate
extension XWSpeechAudiometryBarChartView {
    
    override func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
        guard let set = chartView.data?.dataSets[highlight.dataSetIndex] else { return }
        
        let x = entry.x.int
        let y = entry.y.int

        if set.label == "left" {
            markerView.image = R.image.left_chart_wdrc_marker_bg()
        } else {
            markerView.image = R.image.right_chart_wdrc_marker_bg()
        }
        
        markerView.setLabel("\(x.string)\(volumeUnitText)/\(y.string)")
    }
    
}

